package com.lpf.zerocopy;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class NewIOServer {

    public static void main(String[] arg) throws Exception {

        InetSocketAddress address = new InetSocketAddress(8899);

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //serverSocketChannel.configureBlocking(true);
        // 返回与channel相关联的socket对象
        ServerSocket serverSocket = serverSocketChannel.socket();
        // 当一个TCP连接关闭的时候这个连接会保持一段时间的超时状态，这个状态通常被称为TIME_WAIT状态
        // 当一个 tcp 连接关闭后的一段时间内，这个连接会处于 TIME_WAIT 状态，其他 tcp 连接是不能 bind 这个端口的。
        // 下面这样设置就可以了，也就是当处于 TIME_WAIT 状态时也可以 bind 这个端口。要在 bind 方法之前设置。
        serverSocket.setReuseAddress(true);
        serverSocket.bind(address);

        ByteBuffer buffer = ByteBuffer.allocate(4096);
        while (true) {
            // 接受向这个通道的socket发起的连接，
            // 如果这个channel是非阻塞状态的话，这个方法会立刻返回null
            // 如果是阻塞模式的话，会一直等待连接的到来
            // 这里返回的SocketChannel一定是阻塞的
            SocketChannel socketChannel = serverSocketChannel.accept();

            // 如果设置成 false，会立刻返回 null
            socketChannel.configureBlocking(true);

            int readcount = 0;
            while (-1 != readcount) {
                try {
                    readcount = socketChannel.read(buffer);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                // position被设置成0，mark被丢弃
                buffer.rewind();
            }
        }

    }
}
